1 /**
2    Custom assertions for testing unit-threaded itself, not intended for the end-user.
3  */
4 module unit_threaded.asserts;
5 
6 @safe:
7 
8 /**
9  * Helper to call the standard assert
10  */
11 void assertEqual(T, U)(T t, U u, string file = __FILE__, size_t line = __LINE__) @trusted /* std.conv.to */ {
12     import std.conv : to;
13 
14     assert(t == u,
15             "\n" ~ file ~ ":" ~ line.to!string ~ "\nExp: " ~ u.to!string ~ "\nGot: " ~ t.to!string);
16 }
17 
18 void assertExceptionMsg(E)(lazy E expr, string expected, in string file = __FILE__,
19         in size_t line = __LINE__) {
20     import unit_threaded.should : UnitTestException;
21     import std..string : stripLeft, replace, split;
22     import std.path : dirSeparator;
23     import std.algorithm : map, all, endsWith;
24     import std.range : zip;
25     import std.conv : to, text;
26     import core.exception : AssertError;
27 
28     string getExceptionMsg(E)(lazy E expr) {
29         try {
30             expr();
31         } catch (UnitTestException ex) {
32             return ex.toString;
33         }
34         assert(0, "Expression did not throw UnitTestException");
35     }
36 
37     //updating the tests below as line numbers change is tedious.
38     //instead, replace the number there with the actual line number
39     expected = expected.replace(":123", ":" ~ line.to!string).replace("/", dirSeparator);
40     auto msg = getExceptionMsg(expr);
41     auto expLines = expected.split("\n").map!stripLeft;
42     auto msgLines = msg.split("\n").map!stripLeft;
43     if (!zip(msgLines, expLines).all!(a => a[0].endsWith(a[1]))) {
44         throw new AssertError(text("\nExpected Exception:\n", expected,
45                 "\nGot Exception:\n", msg), file, line);
46     }
47 }